<?php

/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
App::uses('Controller', 'Controller');
Configure::write('recover', false);

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package       app.Controller
 * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller {

    static $loadBlocks = true;
    static $ignore = array('pages', 'js', 'css', 'img', 'ckeditor', 'ckfinder', 'ToolbarAccess');
    public $helpers = array('Form', 'Html', 'Js', 'Time', 'CoreForm');
    //public $components = array('DebugKit.Toolbar');

    public $components = array('Session',
        'Auth' => array('authenticate' => array('Form' => array('userModel' => 'CoreUser',
                    'fields' => array(
                        'username' => 'cous_user',
                        'password' => 'cous_password'
                    )
                )
            ),
            'authorize' => array('Controller'),
            'loginAction' => array('controller' => 'CoreUsers', 'action' => 'block_login'),
            'loginRedirect' => array('controller' => 'CoreUsers', 'action' => 'index'),
            'logoutRedirect' => array('controller' => 'CoreUsers', 'action' => 'block_login'),
        ),
    );

    /**
     * Eu criei o construtor abaixo para poder iniciar o Debug, se nao usar o debug pode apagar
     * @param type $request
     * @param type $response
     */
    function __construct($request = null, $response = null) {
        $locais = array('127.0.0.1', 'localhost', 'LOCALHOST');
        if (in_array($_SERVER["SERVER_NAME"], $locais)) {
            $this->components[] = 'DebugKit.Toolbar';
        }
        parent::__construct($request, $response);
    }

    function beforeFilter() {
        $this->loadSite();
        
        $this->Auth->allow();
        
        $this->setVariables();

        $this->setCurrentModule();

        $this->setPublicPermitions();

        $this->setLanguage();

        if($this->thereIsADatabaseConfig()){
            $this->denyIfNeed();
        }else if($this->Session->read('currentModuleName') != 'CoreInstallation'){ // id does not exists a database configuration try to install
            $this->redirect(array('controller' => 'CoreInstallation', 'action' => 'newInstall'));
        }

        $this->setBlocks();
        //$this->Auth->allow();
    }

    public function beforeRender() {
        
    }

    function loadSite() {
        $url = FULL_BASE_URL . $this->base . "/";
        if(!$this->thereIsADatabaseConfig()){
            return false;
        }
        $coreSite = $this->Session->read('CoreSite');
        if (empty($coreSite) || !empty($_GET['site']) || $coreSite["cosi_url"] != $url) {
            App::import('Controller', 'CoreSites');
            $coreSite = new CoreSitesController();
            $coreSite->constructClasses();
            $coreSite->CoreSite->setBypass(true);
            if (empty($_GET['site'])) {
                $site = $coreSite->CoreSite->find('first', array('conditions' => array('CoreSite.cosi_url' => $url)));
            } else {
                $site = $coreSite->CoreSite->find('first', array('conditions' => array('CoreSite.id' => intval($_GET['site']))));
            }
            if (empty($site)) {// if dont find any get the first one
                $site = $coreSite->CoreSite->find('first');
            }
            if (empty($site)) {// if dont find any return false
                return false;
            }
            $coreSite->CoreSite->setBypass(false);
            $this->log($site['CoreSite']);
            $this->Session->write('CoreSite', $site['CoreSite']);
            $coreSite = $this->Session->read('CoreSite');
        }

        $this->layout = substr($coreSite["cosi_theme"], 0, -4);
    }

    public function isAuthorized() {
        $moduleName = $this->Session->read('currentModuleName');
        $methodName = Configure::read('methodName');
        // if is login or logout or index show it to everybody
        if ($moduleName == 'CoreUsers') {
            $allow = array('login', 'logout', 'block_login');
            if (in_array($methodName, $allow)) {
                return true;
            }
        }
        // if is a block do not check it
        if (preg_match("/^block_/i", $methodName)) {
            return true;
        }
        // check if the user has the module permission
        $user = $this->Session->read('user');
        $moduleId = $this->Session->read('currentModuleId');
        $permition = "No Permition";
        
        if (!empty($moduleId) && !empty($user['permitions']["modulesPrivileges"][$moduleId])) {
            $permition = $user['permitions']["modulesPrivileges"][$moduleId];
            $this->log("Your have permition for this module [$moduleName]");
            if ($moduleName == 'index' || $moduleName == 'view') {
                if ($user['permitions']["modulesPrivileges"][$moduleId] == 'admin' || $user['permitions']["modulesPrivileges"][$moduleId] == 'write' || $user['permitions']["modulesPrivileges"][$moduleId] == 'read') {
                    return true;
                }
            } else if ($moduleName == 'add' || $moduleName == 'edit') {
                if ($user['permitions']["modulesPrivileges"][$moduleId] == 'admin' || $user['permitions']["modulesPrivileges"][$moduleId] == 'write') {
                    return true;
                }
            } else {
                return true;
            }
        }
        $this->log("Your permition for this module [$moduleName] is: {$permition}");
        if ($moduleName == 'index' || $moduleName == 'view' || $moduleName == 'add' || $moduleName == 'edit') {
            return false;
        }

        //var_dump($moduleName, in_array($methodName, $allow), $methodName, $_SESSION['count']++);if($_SESSION['count']>5){exit;}
        return false;
    }

    function isLogged() {
        $user = $this->Session->read('user');
        if (!empty($user['id'])) {
            return true;
        }
        return false;
    }

    private function changeControllerName($oldName) {
        $a = explode("_", $oldName);
        if (count($a) <= 1) {
            return $oldName;
        }
        $newName = "";
        foreach ($a as $value) {
            $newName .= ucfirst($value);
        }
        return $newName;
    }

    static $dataGrid_iconCls = "table--arrow";

    public function dataGrid() {
        eval("\$model = \$this->" . $this->modelClass . ";");
        $fields = $model->getColumnTypes();
        $this->set(compact('fields'));
        $addBlock = $this->requestAction(array('action' => 'add'), array('return'));
        AppController::$loadBlocks = true;
        $this->set(compact('addBlock'));
        $view = getcwd() . DS . ".." . DS . "View" . DS . "{$this->viewPath}" . DS . "data_grid.ctp";
        if (!file_exists($view)) {
            $this->render('/CoreModules/data_grid');
        }
    }

    public function datagrid_data() {
        $rows = $_POST['rows'];
        $page = ($_POST['page'] - 1) * $_POST['rows'];
        self::$loadBlocks = false;
        $this->layout = 'ajax';
        $this->set('model', $this->modelClass);
        eval('$model = $this->' . $this->modelClass . ';');
        //var_dump($this->modelClass);exit;
        $conditions = $order = array();
        if (!empty($_POST['searchBoxValue'])) {
            $conditions = array($_POST['searchBoxName'] . " LIKE" => "%{$_POST['searchBoxValue']}%");
            //$conditions = array("MATCH ({$this->modelClass}.{$_POST['searchBoxName']}) AGAINST ('{$_POST['searchBoxValue']}')");
            //var_dump($conditions);exit;
        }
        if (!empty($_POST['sort'])) {
            $order = array($_POST['sort'] . " " . $_POST['order']);
        }
        $options = array(
            'limit' => "{$page},{$rows}",
            'conditions' => $conditions,
            'order' => $order
        );
        $this->set('rows', $model->find('all', $options));
        $this->set('count', $model->find('count', array('conditions' => $conditions)));
        $view = getcwd() . DS . ".." . DS . "View" . DS . "{$this->viewPath}" . DS . "datagrid_data.ctp";
        if (!file_exists($view)) {
            $this->render('/CoreModules/datagrid_data');
        }
    }

    public function beforeRedirect($url, $status = null, $exit = true) {
        if (!empty($_GET['ajax']) && $_GET['ajax'] == 'true') {
            $this->Session->delete('Message.flash');
            echo "success";
            exit;
        }
    }

    public static function fieldNameToLocale($key) {
        return ucwords(str_replace("_", " ", $key));
    }

    function getBlocksAttributes($id) {
        App::import('Controller', 'CoreBlocks');
        $coreBlock = new CoreBlocksController();
        $coreBlock->constructClasses();
        $block = $coreBlock->CoreBlock->find('first', array('conditions' => array('CoreBlock.id' => $id)));
        if (empty($block["CoreBlock"]["cobl_attributes"])) {
            return null;
        }
        $attributes = unserialize($block["CoreBlock"]["cobl_attributes"]);
        return $attributes;
    }

    function setBlocksAttributes($id) {
        if (!empty($id)) {
            $attributes = $this->getBlocksAttributes($id);
            if (!empty($attributes)) {
                foreach ($attributes as $key => $value) {
                    $this->set($key, $value);
                }
            }
        }
    }

    function setCurrentModule() {
        // only change the current module if the request uri changes
        $request_uri = $this->Session->read('request_uri');
        if (empty($request_uri) || $request_uri != $_SERVER["REQUEST_URI"]) {
            $this->log("Module: " . Configure::read('moduleName'));
            $this->log("Model: " . Configure::read('modelName'));
            $this->log("Method: " . Configure::read('methodName'));
            $this->log("ModuleId: " . Configure::read('moduleId'));
            $this->log("request_uri: " . $_SERVER["REQUEST_URI"]);
            $this->Session->write('currentModuleName', Configure::read('moduleName'));
            $this->Session->write('currentModelName', Configure::read('modelName'));
            $this->Session->write('currentMethodName', Configure::read('methodName'));
            $this->Session->write('currentModuleId', Configure::read('moduleId'));
            $this->Session->write('request_uri', $_SERVER["REQUEST_URI"]);
        }

        $this->set('currentModuleName', $this->Session->read('currentModuleName'));
        $this->set('currentModelName', $this->Session->read('currentModelName'));
        $this->set('currentMethodName', $this->Session->read('currentMethodName'));
        $this->set('currentModuleId', $this->Session->read('currentModuleId'));
        
        Configure::write('currentModuleName', $this->Session->read('currentModuleName'));
        Configure::write('currentModelName', $this->Session->read('currentModelName'));
        Configure::write('currentMethodName', $this->Session->read('currentMethodName'));
        Configure::write('currentModuleId', $this->Session->read('currentModuleId'));
    }

    function setVariables() {
        Configure::write('userId', $this->Session->read('userId'));
        Configure::write('moduleName', $this->changeControllerName($this->request->params['controller']));
        Configure::write('methodName', $this->request->params['action']);
        Configure::write('modelName', $this->modelClass);

        $this->set('moduleName', Configure::read('moduleName'));
        $this->set('methodName', Configure::read('methodName'));
        $this->set('modelName', Configure::read('modelName'));
        if($this->thereIsADatabaseConfig()){
            // get the module ID
            App::import('Controller', 'CoreModules');
            $coreModule = new CoreModulesController();
            $coreModule->CoreModule->setBypass(true);
            $moduleId = $coreModule->getModuleIdFromName(Configure::read('moduleName'));
            $coreModule->CoreModule->setBypass(false);
            Configure::write('moduleId', $moduleId);
        }
    }

    function setPublicPermitions() {
        // if is not logged set the public permition
        App::import('Controller', 'CoreGroups');
        $coreGroups = new CoreGroupsController();

        if (Configure::read('recover')) {
            $this->log("RECOVER MODE IS ON");
            $this->Session->setFlash("RECOVER MODE IS ON");
            $this->Session->write('user', $coreGroups->getByPassPermitions());
            return;
        }

        $user = $this->Session->read('user');

        if (empty($user)) {
            $this->Session->write('user', $coreGroups->getPublicPermitions());
        }
    }

    function setLanguage() {
        // set the language
        $locale = Configure::read('Config.language');
        if ($locale && file_exists($locale . DS . Configure::read('moduleName'))) {
            $this->viewPath = $locale . DS . Configure::read('moduleName');
        }
    }

    function denyIfNeed() {
        $moduleName = Configure::read('moduleName');
        if (!in_array($moduleName, self::$ignore) && $moduleName!='CoreInstallation') {// authorize the main page
            $moduleId = $this->Session->read('currentModuleId');
            // do not show the module if it is not installed        
            if (empty($moduleId)) {
                $this->Session->setFlash(__('The Module %s is NOT installed or inactive', $moduleName));
                $this->Auth->deny();
            }

            // check permitions
            if (!$this->isAuthorized()) {
                $this->Session->setFlash(__('You don´t have permition on the Module %s', $moduleName));
                $this->Auth->deny();
            }
        }
    }

    function setBlocks() {
        if (
                (!empty($_GET['ajax']) && $_GET['ajax'] == 'true') ||
                $this->layout == 'ajax' ||
                (in_array(Configure::read('moduleName'), self::$ignore) && Configure::read('moduleName') != 'pages') ||
                preg_match("/^form_block.*/i", Configure::read('methodName'))
        ) {
            self::$loadBlocks = false;
            $this->layout = 'ajax';
        }

        //var_dump(Configure::read('moduleName'));exit;
        $blocks = array('t' => array(), 'l' => array(), 'c' => array(), 'r' => array(), 'b' => array());
        // if it is not a block get all blocks
        if (self::$loadBlocks == true && $this->thereIsADatabaseConfig()) {
            $moduleId = $this->Session->read('currentModuleId');
            $this->log('Loading blocks: moduleId = ' . $moduleId);
            self::$loadBlocks = false;
            App::import('Controller', 'CoreBlocks');
            $coreBlock = new CoreBlocksController();
            $coreBlock->constructClasses();
            $blocks = $coreBlock->getArrayBlocks($moduleId);
        }
        $this->set("blocks", $blocks);
    }

    /**
     * 
     * @param type $brDate
     * @return String YYYY-MM-DD
     */
    public function dateBrToMySQL($brDate) {
        $parts = explode("/", $brDate);
        //switch month and day
        if (empty($parts[2])) {
            return $brDate;
        } else {
            if (strlen($parts[2]) > 4) { // if there is hour
                $parts2 = explode(" ", $parts[2]);
                $year = $parts2[0];
                $hour = " " . $parts2[1];
            } else {
                $year = $parts[2];
                $hour = "";
            }
            return "{$year}-{$parts[1]}-{$parts[0]}{$hour}";
        }
    }

    /**
     * receive a YYYY-MM-DD
     * @param type $brDate
     * @return String dd/mm/yyyy
     */
    static public function dateMySQLToBrString($mySqlDate) {
        $parts = explode("-", $mySqlDate);
        //switch month and day
        if (empty($parts[2])) {
            return $mySqlDate;
        } else {
            if (strlen($parts[2]) > 2) { // if there is hour
                $parts2 = explode(" ", $parts[2]);
                $day = $parts2[0];
                $hour = " " . $parts2[1];
            } else {
                $day = $parts[2];
                $hour = "";
            }
            return "{$day}/{$parts[1]}/{$parts[0]}{$hour}";
        }
    }

    public function listLayouts() {
        $dir = APP . "View" . DS . "Layouts";
        $files = scandir($dir);
        $layouts = array();
        foreach ($files as $file) {
            if (preg_match('/^(.+)\.ctp$/i', $file)) {
                $layouts[$file] = $file;
            }
        }
        return $layouts;
    }
    
    public function thereIsADatabaseConfig(){
        require_once APP.'/config/database.php';
        $fields = get_class_vars('DATABASE_CONFIG');
        if(!empty($fields['default']['login'])){
            return true;
        }
        return false;
    }
    
    public function checkPermition($permition){
        $user = $this->Session->read('user');
        $moduleId = $this->Session->read('currentModuleId');
        if ((!empty($moduleId) && !empty($user['permitions']["modulesPrivileges"][$moduleId]) && $user['permitions']["modulesPrivileges"][$moduleId] == $permition) || !$this->thereIsADatabaseConfig()) {
            return true;
        }else{
            return false;
        }
    }

}

